/* autor Konjkov.VV@gmail.com */

#include <string>
#include <iostream>
#include <cstdlib>
 
#include "Column.h"
#include "Sqlerr.h"

Column::Column(SQLHENV env, SQLHDBC dbc, SQLHSTMT stmt, SQLUSMALLINT ColumnNumber){

SQLRETURN   retcode;
SQLSMALLINT NameLen;

    SQLColAttributes( stmt, ColumnNumber, SQL_COLUMN_LENGTH, NULL, 0, NULL, &IntLen );
    SQLColAttributes( stmt, ColumnNumber, SQL_COLUMN_DISPLAY_SIZE, NULL, 0 , NULL, &DispLen);
    SQLDescribeCol( stmt, ColumnNumber, Name, sizeof(Name), &NameLen, &SqlType, &Prec, &Scale, &Nullable);

    switch (SqlType) {
    case SQL_CHAR:
    case SQL_VARCHAR:
    case SQL_LONGVARCHAR:
        Value = malloc((IntLen + 1) * sizeof(SQLCHAR));
        TargetType = SQL_C_CHAR;
        break;
    case SQL_BIGINT:
    case SQL_INTEGER:
        Value = malloc(sizeof(SQLINTEGER));
        TargetType = SQL_C_LONG;
        IntLen = 0;
        break;
    case SQL_SMALLINT:
        Value = malloc(sizeof(SQLSMALLINT));
        TargetType = SQL_C_SHORT;
        IntLen = 0;
        break;
    };

    retcode = SQLBindCol( stmt, ColumnNumber, TargetType, Value, IntLen, &StrLen );
    if ( retcode == SQL_ERROR ) {
        std::cerr << __FILE__ << ":" << __LINE__;
        throw Sqlerr(dbc, env, stmt);
    }
};

std::string Column::asString(){
//    if (Nullable == SQL_NULL_DATA) {
//        return std::string("");
//    } else {
        return (char*)(SQLCHAR*)Value;
//    };
};
Column::operator unsigned char*(){
    return (SQLCHAR*)Value;
};

Column::operator int(){
    return *(SQLINTEGER*)Value;
};

Column::operator short(){
    return *(SQLSMALLINT*)Value;
};

Column::~Column(){
};

std::ostream& operator << (std::ostream& out, Column c){
    switch (c.TargetType) {
    case SQL_C_CHAR:
        out << (unsigned char*)c;
        break;
    case SQL_C_LONG:
        out << (int)c;
        break;
    case SQL_C_SHORT:
        out << (short)c;
        break;
    }
    return out;
};
